<!--{
    "Title": "Return a random greeting"
}-->

<p>
  In this section, you'll change your code so that instead of returning a single
  greeting every time, it returns one of several predefined greeting messages.
</p>

<aside class="Note">
  <strong>Note:</strong> This topic is part of a multi-part tutorial that begins
  with <a href="/doc/tutorial/create-module.html">Create a Go module</a>.
</aside>

<p>
  To do this, you'll use a Go slice. A slice is like an array, except that its
  size changes dynamically as you add and remove items. The slice is one of Go's
  most useful types.
</p>

<p>
  You'll add a small slice to contain three greeting messages, then have your
  code return one of the messages randomly. For more on slices,
  see <a href="https://blog.golang.org/slices-intro">Go slices</a> in the Go
  blog.
</p>

<ol>
  <li>
    In greetings/greetings.go, change your code so it looks like the following.

    <pre>
package greetings

import (
    "errors"
    "fmt"
    <ins>"math/rand"
    "time"</ins>
)

// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
    // If no name was given, return an error with a message.
    if name == "" {
        return name, errors.New("empty name")
    }
    // Create a message using a random format.
    message := fmt.Sprintf(<ins>randomFormat()</ins>, name)
    return message, nil
}

<ins>// init sets initial values for variables used in the function.
func init() {
    rand.Seed(time.Now().UnixNano())
}

// randomFormat returns one of a set of greeting messages. The returned
// message is selected at random.
func randomFormat() string {
    // A slice of message formats.
    formats := []string{
        "Hi, %v. Welcome!",
        "Great to see you, %v!",
        "Hail, %v! Well met!",
    }

    // Return a randomly selected message format by specifying
    // a random index for the slice of formats.
    return formats[rand.Intn(len(formats))]
}</ins>
</pre>

    <p>
      In this code, you:
    </p>

    <ul>
      <li>
        Add a <code>randomFormat</code> function that returns a randomly
        selected format for a greeting message. Note that
        <code>randomFormat</code> starts with a lowercase letter, making it
        accessible only to code in its own package (in other words, it's not
        exported).
      </li>
      <li>
        In <code>randomFormat</code>, declare a <code>formats</code> slice with
        three message formats. When declaring a slice, you omit its size in the
        brackets, like this: <code>[]string</code>. This tells Go that the size
        of the array underlying the slice can be dynamically changed.
      </li>
      <li>
        Use the
        <a href="https://pkg.go.dev/math/rand/"
          ><code>math/rand</code> package</a
        >
        to generate a random number for selecting an item from the slice.
      </li>
      <li>
        Add an <code>init</code> function to seed the <code>rand</code> package
        with the current time. Go executes <code>init</code> functions
        automatically at program startup, after global variables have been
        initialized. For more about <code>init</code> functions, see
        <a href="/doc/effective_go.html#init">Effective Go</a>.
      </li>
      <li>
        In <code>Hello</code>, call the <code>randomFormat</code> function to
        get a format for the message you'll return, then use the format and
        <code>name</code> value together to create the message.
      </li>
      <li>Return the message (or an error) as you did before.</li>
    </ul>

  </li>

  <li>
    In hello/hello.go, change your code so it looks like the following.

    <p>You're just adding Gladys's name (or a different name, if you like)
      as an argument to the <code>Hello</code> function call in hello.go.</p>

    <pre>package main

import (
    "fmt"
    "log"

    "example.com/greetings"
)

func main() {
    // Set properties of the predefined Logger, including
    // the log entry prefix and a flag to disable printing
    // the time, source file, and line number.
    log.SetPrefix("greetings: ")
    log.SetFlags(0)

    // Request a greeting message.
    <ins>message, err := greetings.Hello("Gladys")</ins>
    // If an error was returned, print it to the console and
    // exit the program.
    if err != nil {
        log.Fatal(err)
    }

    // If no error was returned, print the returned message
    // to the console.
    fmt.Println(message)
}</pre>
  </li>

  <li>
    At the command line, in the hello directory, run hello.go to confirm that
    the code works. Run it multiple times, noticing that the greeting changes.

    <pre>
$ go run .
Great to see you, Gladys!

$ go run .
Hi, Gladys. Welcome!

$ go run .
Hail, Gladys! Well met!
</pre>
  </li>
</ol>

<p>
  Next, you'll use a slice to greet multiple people.
</p>

<p class="Navigation">
  <a class="Navigation-prev" href="/doc/tutorial/handle-errors.html"
    >&lt; Return and handle an error</a
  >
  <a class="Navigation-next" href="/doc/tutorial/greetings-multiple-people.html"
    >Return greetings for multiple people &gt;</a
  >
</p>
